package cn.kgc.auth.service;

import cn.kgc.auth.vo.PhoneApi;
import cn.kgc.dto.Dto;
import cn.kgc.mapper.UserMapper;
import cn.kgc.pojo.User;
import cn.kgc.util.DtoUtil;
import cn.kgc.util.MD5Utils;
import cn.kgc.util.TokenUtil;
import cn.kgc.util.UUIDUtil;
import cn.kgc.vo.IlxToken;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.StringUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/*
   1  用户
       10001 登录
       1002 注册

   2  订单
   3  主页面
   4  搜索、
*/
@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private JavaMailSender javaMailSender;
    @Resource
    private SimpleMailMessage simpleMailMessage;
    @Resource
    private PhoneApi phoneApi;
    @Override
    public Dto isExist(String userCode) {
        User user =new User();
        user.setUserCode(userCode);
        boolean judgeExist=userMapper.selectCount(user)==0;
        if (!judgeExist){
            return DtoUtil.getFalseDto("该用户名已存在","10002");
        }
        return DtoUtil.getSuccessDto("可以注册");
    }

    @Override
    public Dto register(User user) {
        //1 先添加 未激活状态
        user.setCreationDate(new Date());
        user.setModifyDate(new Date());
        //密码需要加密
        String password = MD5Utils.encodeStr(user.getUserPassword());
        user.setUserPassword(password);
        if (!(userMapper.insert(user)>0)){
            return DtoUtil.getFalseDto("添加失败，请联系管理员","10001");
        }
        //2 生成验证码 UUID
        String code= UUIDUtil.getStr(false);
        //3 保存验证码到redis
        stringRedisTemplate.opsForValue().set(user.getUserCode(),code,1*60*24, TimeUnit.MINUTES);
        //发送邮件
        simpleMailMessage.setText("欢迎注册我们的网站，您的验证码是"+code+"一天内有效，请尽快激活！");
        simpleMailMessage.setTo(user.getUserCode());
        javaMailSender.send(simpleMailMessage);
        return DtoUtil.getSuccessDto("消息发送成功！");
    }

    @Override
    public Dto activeUser(String userCode, String code) {
        //1 看是不是有这个用户
        if (!stringRedisTemplate.hasKey(userCode)){
            return DtoUtil.getFalseDto("用户不存在或者已经激活","100003");
        }
        if (StringUtil.isEmpty(code)){
            return DtoUtil.getFalseDto("验证码不能为空","100005");
        }
        User userX=new User();
        userX.setUserCode(userCode);
        User userT=userMapper.selectOne(userX);
        userT.setActivated(1);
//        System.out.println(userX.getActivated());
        //3 修改用户的状态为激活
        userMapper.updateByPrimaryKey(userT);
//        System.out.println(userMapper.selectOne(userX));
        //4 删掉redis中的code
        stringRedisTemplate.delete(userCode);
        //5 给用户响应
        return DtoUtil.getSuccessDto("激活成功！");
    }

    @Override
    public Dto registerByphone(User user) {
        //1 先添加 未激活状态
        user.setCreationDate(new Date());
        user.setModifyDate(new Date());
        user.setActivated(0);
        //密码需要加密
        String password = MD5Utils.encodeStr(user.getUserPassword());
        user.setUserPassword(password);
        if (!(userMapper.insert(user)>0)) {
            return DtoUtil.getFalseDto("添加失败，联系管理员","10001");
        }
        //2 生成验证码 UUID
        Random random=new Random();
        String code=random.nextInt(10)+""+random.nextInt(10)+random.nextInt(10)+random.nextInt(10);
        //3 保存验证码到redis
        stringRedisTemplate.opsForValue().set(user.getUserCode(),code,3, TimeUnit.MINUTES);
        //4 发送短信
        phoneApi.sendTemplateSMS(user.getUserCode(),"1",new String[]{code,1+""});
        return DtoUtil.getSuccessDto("消息发送成功！");
    }

    @Override
    public Dto sendCodeToPhone(String userCode) {
        //1 生成验证码 UUID
        Random random=new Random();
        String code=random.nextInt(10)+""+random.nextInt(10)+random.nextInt(10)+random.nextInt(10);
        //2 保存验证码到redis
        stringRedisTemplate.opsForValue().set(userCode,code,3, TimeUnit.MINUTES);
        //3 发送短信
        phoneApi.sendTemplateSMS(userCode,"1",new String[]{code,1+""});
        return DtoUtil.getSuccessDto("消息发送成功！");
    }

    @Override
    public Dto<IlxToken> selectByLogin(String userCode,String password,String from) {
        User t=new User();
        t.setUserCode(userCode);
        t.setUserPassword(MD5Utils.encodeStr(password));
        t=userMapper.selectOne(t);
        if (ObjectUtils.isEmpty(t)){
            return DtoUtil.getFalseDto("用户密码不匹配","10006");
        }
        if (t.getActivated()==0){
            return DtoUtil.getFalseDto("用户没有激活","10007");
        }
        //生成一个token,保存到redis,将token的结果返回给前端
        //规则：请求来源-用户编码 -用户ID -时间 -随机6位
        Date date=new Date();
        int time = 30;
        if (!from.equals("pc")){
            time=Integer.MAX_VALUE;
        }
        String token = TokenUtil.getToken(from,date,t.getUserCode(),t.getId(),6,false);
//        String token="token:"+from+"-"+MD5Utils.encodeStr(t.getUsercode())+"-"+t.getId()+"-"+getTimeStr(date)+"-"+ UUIDUtil.getStr(6,false);
//        stringRedisTemplate.opsForValue().set("token",token,time,TimeUnit.MINUTES);
        stringRedisTemplate.opsForValue().set(token, JSONArray.toJSONString(t),30,TimeUnit.MINUTES);
        IlxToken ilxToken=new IlxToken();
        ilxToken.setGenTime(date.getTime());
        ilxToken.setExpTime((date.getTime()+time*60*1000));
        ilxToken.setToken(token);
        return DtoUtil.getSuccesWithData(ilxToken);
    }

    @Override
    public Dto logout(String token) {
        //1 判断是否登录
         if (StringUtil.isEmpty(token)){
             return DtoUtil.getFalseDto("还未登录怎么注销","10008");
         }
         if (!stringRedisTemplate.hasKey(token)){
             return DtoUtil.getFalseDto("还未登录怎么注销","10009");
         }
        //2 删除redis中的token
        stringRedisTemplate.delete(token);
        return DtoUtil.getSuccessDto("注销成功！");
    }

    @Override
    public Dto reToken(String token) {
        //1 验证token是否有效
        if (!stringRedisTemplate.hasKey(token)){
            return DtoUtil.getFalseDto("不存在该token","10011");
        }
        if (!token.startsWith("token:pc")){
            return DtoUtil.getFalseDto("移动端用户不需要重置","10010");
        }
        User t=JSON.parseObject(stringRedisTemplate.opsForValue().get(token),User.class);
        //能不能置换
        Date date=new Date();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
        try {
            Date genTime=sdf.parse(token.split("-")[3]);
            long passed= Calendar.getInstance().getTimeInMillis()-genTime.getTime();
            if (passed<25*60*1000){
                return DtoUtil.getFalseDto("还未到重置时间","10012");
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //进行置换
        stringRedisTemplate.delete(token);
        String newToken=TokenUtil.getToken("pc",date,t.getUserCode(),t.getId(),6,false);
        //token.split("-")[0]+"-"+token.split("-")[1]+"-"+token.split("-")[2]+"-"+getTimeStr(date)+"-"+ UUIDUtil.getStr(6,false);
        stringRedisTemplate.opsForValue().set(newToken,JSONArray.toJSONString(t),30,TimeUnit.MINUTES);
        IlxToken ilxToken=new IlxToken();
        ilxToken.setGenTime(date.getTime());
        ilxToken.setExpTime((date.getTime()+30*60*1000));
        ilxToken.setToken(newToken);
        return DtoUtil.getSuccesWithData(ilxToken);
    }
}
